#ifndef COMPILE_JVM_H
#define COMPILE_JVM_H

#include <stack>

#include "CompileVisitor.h"
#include "jtypes.h"
#include "MethodInfo.h"
#include "RelocTable.h"
#include "ClassFile.h"
#include "SymbolPool.h"

class CompileJvm : public CompileVisitor
{
  public:
    CompileJvm(const char * classname);

    virtual int finalize();

    virtual int compile(AstNodeLiteral *);
    virtual int compile(AstNodeStatementList *);
    virtual int compile(AstNodeLValue*);
    virtual int compile(AstNodeBooleanOperator *);
    virtual int compile(AstNodeAssignment *);
    virtual int compile(AstNodeExpressionVariable *);
    virtual int compile(AstNodeDoubleConstant *);
    virtual int compile(AstNodeBinaryOperator *);
    virtual int compile(AstNodeCompareExpression *);
    virtual int compile(AstNodeForStatement *);
    virtual int compile(AstNodeIfStatement *);
    virtual int compile(AstNodePrintLiteral *);
    virtual int compile(AstNodePrintExpression *);
  private:

    inline RelocTable * relocOnTruePush()
    {
      RelocTable * rt=new RelocTable();
      relocOnTrueStack.push(rt);
      return rt;
    };

    inline RelocTable * relocOnFalsePush()
    {
      RelocTable * rt=new RelocTable();
      relocOnFalseStack.push(rt);
      return rt;
    };

    inline RelocTable * relocOnTrueTop() { return relocOnTrueStack.top(); }
    inline RelocTable * relocOnFalseTop() { return relocOnFalseStack.top(); }

    inline void relocOnFalsePop() 
    { 
      RelocTable * rt;
      rt=relocOnFalseStack.top();
      delete rt;
      relocOnFalseStack.pop();
    }

    inline void relocOnTruePop() 
    { 
      RelocTable * rt;
      rt=relocOnTrueStack.top();
      delete rt;
      relocOnTrueStack.pop();
    }

    inline void relocOnTrueFalseSwitch() 
    {
      RelocTable * t;
      RelocTable * f;
      t=relocOnTrueStack.top();
      f=relocOnFalseStack.top();

      relocOnTrueStack.pop();
      relocOnFalseStack.pop();

      relocOnTrueStack.push(f);
      relocOnFalseStack.push(t);
    }

    ClassFile *  klass;  
    MethodInfo * method;
    SymbolPool * symbols;
    std::stack<RelocTable*> relocOnTrueStack;
    std::stack<RelocTable*> relocOnFalseStack;
};


#endif 
